//////////////////////////////////////////////////////////////////////////
//
// GAM203
// Cube class
// Cube.cpp
// 
// Grant Johnson
// Qantm College
// 27/10/2010
//
//////////////////////////////////////////////////////////////////////////
#include "Cube.h"
#include <d3dx9.h>
#include "ShaderMgr.h"
#include "Shader.h"
#include "Renderer.h"
#include "RenderParams.h"

Cube::Cube()
: m_selected(false)
{
}
Cube::~Cube()
{
}
void Cube::SetSelected(bool a_val)
{
	m_selected = a_val; 
}
bool Cube::CreateObject(IDirect3DDevice9* a_pDevice, char* a_pTexFileName)
{
	if(!a_pDevice)
	{
		return false;
	}

	D3DXCreateBox(a_pDevice, 1.0f, 1.0f, 1.0f, &m_pMesh, NULL);

	return true;
}

void Cube::Render(float a_dt, IDirect3DDevice9 *a_pDevice, const RenderParams& a_renderParams)
{
		// Tell D3D about our vertex data
		a_pDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(VertexData));
		a_pDevice->SetFVF(VERTEX_FORMAT_FVF);

		a_pDevice->SetIndices(m_pIndexBuffer);

		const char* SHADER_NAME = "AdvancedShader";
		Shader* pShader = ShaderMgr::GetInstance().Find(SHADER_NAME);
		if(pShader)
		{
			ID3DXEffect* pEffect = pShader->GetEffect();
			if(pEffect)
			{
				pEffect->SetTechnique("AdvRenderDiff0Spec0Dir1Omni1NoCol");

				pEffect->SetValue("g_fogColor", &D3DXCOLOR(0.3f, 0.35f, 0.4f, 1.0f), sizeof(D3DXCOLOR));

				pEffect->SetFloat("g_fogDistStart", 10);
				pEffect->SetFloat("g_fogDistEnd", 200);
				pEffect->SetValue("g_cameraPos", Renderer::GetInstance().GetActiveCamera()->GetEyePos(), sizeof(D3DXVECTOR3));

				//Set up lighting global variables
				for(int lightId = 0; lightId < a_renderParams.GetLightCount(); ++lightId)
				{
					if(a_renderParams.GetLight(lightId)->Type == D3DLIGHT_DIRECTIONAL)
					{
						//Set lighting parameters
						//Note: Light direction is negated to optimise the dot product in 
						//shader calculations
						pEffect->SetValue("g_directionalDir", &(D3DXVECTOR3(a_renderParams.GetLight(lightId)->Direction) * -1.0f), sizeof(D3DXVECTOR3));
						pEffect->SetValue("g_directionalDiffuse", &D3DXCOLOR(a_renderParams.GetLight(lightId)->Diffuse), sizeof(D3DXCOLOR));
						pEffect->SetValue("g_directionalSpecular", &D3DXCOLOR(a_renderParams.GetLight(lightId)->Specular), sizeof(D3DXCOLOR));
					}
					else if(a_renderParams.GetLight(lightId)->Type == D3DLIGHT_POINT)
					{
						pEffect->SetValue("g_omniPos", &D3DXVECTOR3(a_renderParams.GetLight(lightId)->Position), sizeof(D3DXVECTOR3));
						pEffect->SetFloat("g_omniRange", a_renderParams.GetLight(lightId)->Range);
						pEffect->SetValue("g_omniDiffuse", &D3DXCOLOR(a_renderParams.GetLight(lightId)->Diffuse), sizeof(D3DXCOLOR));
						pEffect->SetValue("g_omniSpecular", &D3DXCOLOR(a_renderParams.GetLight(lightId)->Specular), sizeof(D3DXCOLOR));
					}
				}
				pEffect->SetValue("g_totalAmbient", &D3DXCOLOR(a_renderParams.GetGlobalAmbient()), sizeof(D3DXCOLOR));
				
				//Set matrix global variables
				//Calculate a combined world*view*proj matrix for the vertex shader
				D3DXMATRIX worldViewProj = m_worldMatrix*a_renderParams.GetViewMatrix()*a_renderParams.GetProjMatrix();
				pEffect->SetMatrix("g_worldViewProj", &worldViewProj);
				pEffect->SetMatrix("g_worldMat", &m_worldMatrix);

				//Render with shader
				UINT passCount = 0;
				if(pEffect->Begin(&passCount, 0) == D3D_OK)
				{
					for(UINT passIndex = 0; passIndex < passCount; ++passIndex)
					{		
						if(pEffect->BeginPass(passIndex) == D3D_OK)
						{
							//Draw the cube
							if(m_selected)
								a_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
							m_pMesh->DrawSubset(0);
							a_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

							pEffect->EndPass();
						}
					}
					pEffect->End();
				}
			}
		}
		
}